package com.huawei.hms.framework.network.restclient;

import com.huawei.hms.framework.common.ContainerUtils;
import com.huawei.hms.framework.network.restclient.hwhttp.ClientConfiguration;
import com.huawei.hms.framework.network.restclient.hwhttp.FormBody.Builder;
import com.huawei.hms.framework.network.restclient.hwhttp.HttpContants;
import com.huawei.hms.framework.network.restclient.hwhttp.Request;
import com.huawei.hms.framework.network.restclient.hwhttp.RequestBody;
import com.huawei.hms.framework.network.restclient.hwhttp.url.HttpUrl;
import com.huawei.hms.framework.network.util.HttpUtils;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import javax.annotation.Nullable;

public final class RequestBuilder {
    private static final Pattern PATH_TRAVERSAL = Pattern.compile("(.*/)?(\\.|%2e|%2E){1,2}(/.*)?");
    private HttpUrl baseUrl;
    @Nullable
    private RequestBody body;
    private ClientConfiguration clientConfig;
    private String contentType;
    @Nullable
    private Builder formBuilder;
    private boolean hasBody;
    private boolean isOnlyConnect;
    private String method;
    private Map<String, String> queryParamMap;
    private String relativeUrl;
    private final Request.Builder requestBuilder = new Request.Builder();

    static class ContentTypeOverridingRequestBody extends RequestBody {
        private final RequestBody delegate;
        private final String overrideContentType;

        ContentTypeOverridingRequestBody(RequestBody requestBody, String str) {
            this.delegate = requestBody;
            this.overrideContentType = str;
        }

        public String contentType() {
            return this.overrideContentType;
        }

        public long contentLength() {
            return this.delegate.contentLength();
        }

        public byte[] body() {
            return this.delegate.body();
        }
    }

    RequestBuilder(String str, HttpUrl httpUrl, @Nullable String str2, @Nullable Headers headers, @Nullable String str3, boolean z, boolean z2, boolean z3) {
        this.method = str;
        this.baseUrl = httpUrl;
        this.relativeUrl = str2;
        this.contentType = str3;
        this.hasBody = z;
        this.isOnlyConnect = z3;
        if (headers != null) {
            this.requestBuilder.headers(headers.newBuilder());
        }
        if (z2) {
            this.formBuilder = new Builder();
        }
    }

    public HttpUrl getRequestUrl() throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        if (HttpUtils.isHttpOrGrsUrl(this.relativeUrl)) {
            stringBuilder.append(this.relativeUrl);
        } else if (this.baseUrl == null) {
            throw new IOException("baseUrl == null", new NullPointerException("baseUrl == null"));
        } else {
            stringBuilder.append(this.baseUrl.getUrl());
            stringBuilder.append(this.relativeUrl);
        }
        String queryParam = getQueryParam();
        if (!queryParam.isEmpty()) {
            int lastIndexOf = stringBuilder.lastIndexOf("?");
            int length = stringBuilder.length();
            if (lastIndexOf < 0) {
                stringBuilder.append("?").append(queryParam);
            } else if (lastIndexOf == length - 1) {
                stringBuilder.append(queryParam);
            } else {
                stringBuilder.append(ContainerUtils.FIELD_DELIMITER).append(queryParam);
            }
        }
        return new HttpUrl(stringBuilder.toString());
    }

    public String getRelativeUrl() {
        return this.relativeUrl;
    }

    void setRelativeUrl(String str) {
        this.relativeUrl = str;
    }

    void addQueryParam(String str, String str2) {
        if (this.queryParamMap == null) {
            this.queryParamMap = new HashMap();
        }
        this.queryParamMap.put(str, str2);
    }

    private String getQueryParam() {
        StringBuilder stringBuilder = new StringBuilder();
        if (!(this.queryParamMap == null || this.queryParamMap.isEmpty())) {
            Iterator it = this.queryParamMap.entrySet().iterator();
            while (it.hasNext()) {
                Entry entry = (Entry) it.next();
                stringBuilder.append((String) entry.getKey());
                stringBuilder.append(ContainerUtils.KEY_VALUE_DELIMITER);
                stringBuilder.append((String) entry.getValue());
                if (it.hasNext()) {
                    stringBuilder.append(ContainerUtils.FIELD_DELIMITER);
                }
            }
        }
        return stringBuilder.toString();
    }

    public String getMethod() {
        return this.method;
    }

    public boolean hasBody() {
        return this.hasBody;
    }

    void addHeader(String str, String str2) {
        if (HttpContants.KEY_CONTENT_TYPE.equalsIgnoreCase(str)) {
            this.contentType = str2;
        } else {
            this.requestBuilder.addHeader(str, str2);
        }
    }

    void addPathParam(String str, String str2) {
        if (this.relativeUrl == null) {
            throw new AssertionError();
        }
        Object replace = this.relativeUrl.replace("{" + str + "}", str2);
        if (PATH_TRAVERSAL.matcher(replace).matches()) {
            throw new IllegalArgumentException("@Path parameters shouldn't perform path traversal ('.' or '..'): " + str2);
        }
        this.relativeUrl = replace;
    }

    void addFormField(String str, String str2) {
        if (this.formBuilder != null) {
            this.formBuilder.add(str, str2);
        }
    }

    void setBody(RequestBody requestBody) {
        this.body = requestBody;
    }

    public void setClientConfig(ClientConfiguration clientConfiguration) {
        this.clientConfig = clientConfiguration;
    }

    Request build() throws IOException {
        RequestBody requestBody = this.body;
        if (requestBody == null) {
            if (this.formBuilder != null) {
                requestBody = this.formBuilder.build();
            } else if (hasBody()) {
                requestBody = RequestBody.create(null, new byte[0]);
            }
        }
        if (this.contentType != null) {
            if (requestBody != null) {
                requestBody = new ContentTypeOverridingRequestBody(requestBody, this.contentType);
            } else {
                this.requestBuilder.addHeader(HttpContants.KEY_CONTENT_TYPE, this.contentType);
            }
        }
        this.requestBuilder.url(getRequestUrl()).method(this.method).requestBody(requestBody).onlyConnect(this.isOnlyConnect);
        if (this.clientConfig != null) {
            this.requestBuilder.connectTimeout(this.clientConfig.getConnectTimeout()).readTimeout(this.clientConfig.getReadTimeout()).retryTimeOnConnectionFailure(this.clientConfig.getRetryTimeOnConnectionFailure());
        }
        return this.requestBuilder.build();
    }
}
